package com.blacksea.authserver.web.configuration;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;
import java.util.TimeZone;

/**
 * WebConfig
 *
 * @author blacksea3(jxt) 2021/4/11 14:33
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {
    private static final int ACCESS_CONTROL_MAX_AGE = 3600;

    /**
     * 允许跨域访问
     *
     * @param registry .
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("*")
            .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
            .allowCredentials(true)
            .maxAge(ACCESS_CONTROL_MAX_AGE)
            .allowedHeaders("*");
    }

    /**
     * 统一序列化风格: 针对MappingJackson2HttpMessageConverter, POJO与json转换
     * See {@link com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy} for details.
     * @param converters .
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (int i = 0; i < converters.size(); i++) {
            if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) {
                ObjectMapper objectMapper = new ObjectMapper();
                // 修改Json 序列化与反序列化的策略：小写字母下划线策略
                objectMapper.setPropertyNamingStrategy(new PropertyNamingStrategy.SnakeCaseStrategy());
                // 属性为null的不参与序列化与反序列化
                objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
                // 出现未知属性(field)时抛出异常JsonMappingException
                objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                // 时区修改
                objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
                // 新的MappingJackson2HttpMessageConverter构造
                MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
                converter.setObjectMapper(objectMapper);
                // 替换MappingJackson2HttpMessageConverter
                converters.set(i, converter);
                break;
            }
        }
    }
}
